//
//  VerificationCodeViewModel.swift
//  casdon_swiftUI
//
//  Created by ww on 2025/4/20.
//

import Combine
class VerificationCodeViewModel: ObservableObject {
    @Published var account: String?
    @Published var type: RequestCodeType = .notRegister   // 请求验证码的类型，用于重新请求验证码
    @Published var verifyType: ValidateCodeType = .loginOrBinding // 校验验证码时传递的类型。
    @Published var code: [String] = Array(repeating: "", count: 6)
    @Published var showToast: Bool = false
    @Published var toastMsg: String = ""
    @Published var isLoading: Bool = false
    @Published var resendCodeSuccess: Bool = false
    @Published var verifyCodeSuccess: Bool = false
    
    let navigateToNext = PassthroughSubject<(String, Bool), Never>()
    lazy var autoSubmitTrigger: AnyPublisher<Void, Never> = {
        $code
            .debounce(for: .milliseconds(200), scheduler: RunLoop.main)
            .map { $0.joined().count }
            .filter { $0 == 6 }
            .map { _ in () }
            .eraseToAnyPublisher()
    }()

    
    @Published var remainingSeconds: Int = 0
    private var timeerCancelable: AnyCancellable?
    
    
    var cancellables = Set<AnyCancellable>()
    
    func verificationCodePublisher() -> AnyPublisher<String, Never> {
        NotificationCenter.default
            .publisher(for: .verificationCodeEntered)
            .compactMap { notification in
                notification.userInfo?["code"] as? String
            }
            .eraseToAnyPublisher()
    }
    
    
    init(account: String, type: RequestCodeType, verifyType: ValidateCodeType) {
        self.account = account
        self.type = type
        self.verifyType = verifyType
        timeOutStart()
        autoSubmitTrigger
               .sink { [weak self] in
                   if verifyType == .loginOrBinding {
                       self?.login()
                   }
                   else{
                       self?.verifyCode()
                   }
               }
               .store(in: &cancellables)
    }
    
    
    
    // 登录
    func login() {
        let codeString = code.joined()
        // 登录
        guard let account = account else {
            print("119615 account 为空")
            return
        }
        CDCodeLoginStep().execute(.init(phonenumber: account, smsCode: codeString))
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: {[weak self] completion in
                switch completion {
                case .finished:
                    print("119615, 验证码登录 finished")
                    self?.isLoading = false
                case .failure(let error):
                    print("119615, 验证码登录 error: \(error)")
                    self?.showToast = true
                    self?.isLoading = false
                    self?.toastMsg = error.localizedDescription
                }
            }, receiveValue: {[weak self] userInfo in
                print("119615, 验证码登录 value: \(userInfo)")
                AuthManager.shared.saveToken(userInfo.access_token)
                self?.tuyaPwdLogin()
                self?.isLoading = false
            })
            .store(in: &cancellables)
    }
    
    
    private func tuyaPwdLogin()
    {
        isLoading = true
        TuyaPwdLoginFlow().start()
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: {[weak self] completion in
                switch completion {
                case .finished:
                    print("119615, 验证码登录 finished")
                    self?.isLoading = false
                case .failure(let error):
                    print("119615, 验证码登录 error: \(error)")
                    self?.showToast = true
                    self?.isLoading = false
                    self?.toastMsg = error.localizedDescription
                }
            }, receiveValue: {[weak self] userInfo in
                print("119615, 验证码登录 value: \(userInfo)")
                self?.isLoading = false
            })
            .store(in: &cancellables)
    }
    
    func reSendVerifyCode() {
        isLoading = true
        resendCodeSuccess = false
        guard let account = account else {
            print("119615 account 为空")
            return
        }
        CDGetVerifyCodeStep().execute(.init(account: account, type: .notRegister))
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: {[weak self] completion in
                switch completion {
                case .finished:
                    print("119615, 重新获取验证码 finished")
                    self?.resendCodeSuccess = true
                    self?.isLoading = false
                case .failure(let error):
                    print("119615, 重新获取验证码 error: \(error)")
                    self?.showToast = true
                    self?.isLoading = false
                    self?.toastMsg = error.localizedDescription
                }
            }, receiveValue: {[weak self] userInfo in
                print("119615, 重新获取验证码 value: \(userInfo)")
                self?.resendCodeSuccess = true
                self?.isLoading = false
                self?.timeOutStart()
            })
            .store(in: &cancellables)
    }
    
    // 校验验证码
    func verifyCode()
    {
        isLoading = true
        guard let account = account else {
            print("119615 account 为空")
            return
        }
        let codeString = code.joined()
        CDValidateCodeStep().execute(.init(userName: account, code: codeString, type: verifyType))
            .receive(on: DispatchQueue.main)
            .sink(receiveCompletion: {[weak self] completion in
                switch completion {
                case .finished:
                    print("119615, 校验验证码 finished")
                    self?.isLoading = false
                case .failure(let error):
                    print("119615, 校验验证码  error: \(error)")
                    self?.showToast = true
                    self?.isLoading = false
                    self?.toastMsg = error.localizedDescription
                }
            }, receiveValue: {[weak self] result in
                print("119615, 校验验证码  value: \(result)")
                self?.isLoading = false
                self?.verifyCodeSuccess = result
                if !result {
                    self?.showToast = true
                    self?.toastMsg = "验证码错误"
                }
             
            })
            .store(in: &cancellables)
    }
    
    
     func timeOutStart() {
           // 防止重复启动
        if remainingSeconds > 0 { return }
          
           remainingSeconds = 60
          
        timeerCancelable = Timer.publish(every: 1, on: .main, in: .common)
                    .autoconnect()
                    .scan(60) { (secondsLeft: Int, _) -> Int in
                        secondsLeft - 1
                    }
                    .prefix(while: { $0 >= 0 })
                    .sink { [weak self] seconds in
                        self?.remainingSeconds = seconds
                        if seconds == 0 {
                            self?.timeerCancelable?.cancel()
                        }
            }
       }
}
